package com.cq.hd.admin.biz;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSON;
import com.cq.hd.common.enums.biz.ActiveEnrollInfoTypeEnum;
import com.cq.hd.common.enums.biz.SubOrderStateEnum;
import com.cq.hd.common.utils.GenerateUtil;
import com.cq.hd.common.utils.LocalDateUtil;
import com.cq.hd.common.utils.StringUtils;
import com.cq.hd.order.api.TbOrderApi;
import com.cq.hd.order.api.dto.*;
import com.cq.hd.order.api.excel.*;
import com.cq.hd.order.api.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
@Slf4j
public class OrderBiz {

    @Autowired
    private TbOrderApi orderApi;

    public void exportActiveVerifyRecord(ActiveVerifyRecordQueryDto adminActiveVerifyRecordPageDto, HttpServletResponse response) {
        List<AdminVerifyRecordPageVo> list = orderApi.listAdminVerifyRecord(adminActiveVerifyRecordPageDto).unpack();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // 订单明细sheet
        List<VerifyRecordSheet> orderSheets = new ArrayList<>();
        setVerifyRecordData(list, orderSheets);

        LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();
        String fileName = "核销明细" + LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(6);

        // 多个sheet的输出需要使用ExcelWriter类，这里想要下载成功，需要输出到OutputStream中
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).inMemory(true).build()) {
            // 设置响应类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            // 设置编码格式
            response.setCharacterEncoding("utf-8");
            // 设置跨域
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD, PUT");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "*");
            // 设置响应头
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");

            WriteSheet enrollOrderSheet = EasyExcel.writerSheet(0, "订单明细")
                    .registerWriteHandler(new CustomWriteHandler())
                    .head(VerifyRecordSheet.class).build();
            excelWriter.write(orderSheets, enrollOrderSheet);
        } catch (Exception ioException) {
            ioException.printStackTrace();
        }
    }

    /**
     * 根据提现单ID，导出相关联的订单
     *
     * @param withdrawalId
     * @param response
     */
    public void exportOrderByWithdrawalId(Long withdrawalId, HttpServletResponse response) {
        // 根据条件获取订单数据
        List<AdminOrderPageVo> list = orderApi.listByWithdrawalId(withdrawalId).unpack();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // 订单明细sheet
        List<GroupOrderSheet> orderSheets = new ArrayList<>();
        setOrderData(list, orderSheets);

        LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();
        String fileName = "订单明细" + LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(6);

        // 多个sheet的输出需要使用ExcelWriter类，这里想要下载成功，需要输出到OutputStream中
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).inMemory(true).build()) {
            // 设置响应类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            // 设置编码格式
            response.setCharacterEncoding("utf-8");
            // 设置跨域
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD, PUT");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "*");
            // 设置响应头
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");

            List<List<String>> mergeColDataList = Stream.of(orderSheets.stream().map(GroupOrderSheet::getOrderNo).collect(Collectors.toList())
            ).collect(Collectors.toList());
            List<Integer> mergeColIndexList = Stream.of(0).collect(Collectors.toList());

            WriteSheet enrollOrderSheet = EasyExcel.writerSheet(0, "订单明细")
                    .registerWriteHandler(new CustomWriteHandler())
                    .registerWriteHandler(new CustomCellMergeStrategy(mergeColDataList, mergeColIndexList))
                    .head(GroupOrderSheet.class).build();
            excelWriter.write(orderSheets, enrollOrderSheet);
        } catch (Exception ioException) {
            ioException.printStackTrace();
        }
    }

    public void exportPointsOrderExcel(AdminPointsOrderPageDto adminPointsOrderPageDto, HttpServletResponse response) {
        // 根据条件获取订单数据
        List<AdminPointsOrderPageVo> list = orderApi.listAdminPointsOrder(adminPointsOrderPageDto).unpack();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // 组装订单明细sheet
        List<PointsOrderSheet> pointsOrderSheets = new ArrayList<>();
        // 组装订单汇总sheet
        List<TotalPointsOrderSheet> totalPointsOrderSheets = new ArrayList<>();
        setPointsOrderData(list, pointsOrderSheets, totalPointsOrderSheets);

        LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();
        String fileName = "积分订单明细" + LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(6);

        // 多个sheet的输出需要使用ExcelWriter类，这里想要下载成功，需要输出到OutputStream中
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).inMemory(true).build()) {
            // 设置响应类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            // 设置编码格式
            response.setCharacterEncoding("utf-8");
            // 设置跨域
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD, PUT");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "*");
            // 设置响应头
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");

            List<List<String>> mergeColDataList = Stream.of(pointsOrderSheets.stream().map(PointsOrderSheet::getOrderNo).collect(Collectors.toList())
            ).collect(Collectors.toList());
            List<Integer> mergeColIndexList = Stream.of(0).collect(Collectors.toList());

            WriteSheet pointsOrderSheet = EasyExcel.writerSheet(0, "订单明细")
                    .registerWriteHandler(new CustomWriteHandler())
                    .registerWriteHandler(new CustomCellMergeStrategy(mergeColDataList, mergeColIndexList))
                    .head(PointsOrderSheet.class).build();
            excelWriter.write(pointsOrderSheets, pointsOrderSheet);
            WriteSheet pointsOrderSummarySheet = EasyExcel.writerSheet(1, "订单汇总")
                    .registerWriteHandler(new CustomWriteHandler()).head(TotalPointsOrderSheet.class).build();
            excelWriter.write(totalPointsOrderSheets, pointsOrderSummarySheet);
        } catch (Exception ioException) {
            ioException.printStackTrace();
        }
    }

    public void exportCommissionOrderExcel(AdminCommissionOrderPageDto adminCommissionOrderPageDto, HttpServletResponse response) {
        List<AdminCommissionOrderPageVo> list = orderApi.listAdminCommissionOrder(adminCommissionOrderPageDto).unpack();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // 订单明细sheet
        List<CommissionOrderSheet> orderSheets = new ArrayList<>();
        setCommissionOrderData(list, orderSheets);

        LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();
        String fileName = "佣金列表" + LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(6);

        // 多个sheet的输出需要使用ExcelWriter类，这里想要下载成功，需要输出到OutputStream中
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).inMemory(true).build()) {
            // 设置响应类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            // 设置编码格式
            response.setCharacterEncoding("utf-8");
            // 设置跨域
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD, PUT");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "*");
            // 设置响应头
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");

            WriteSheet orderSheet = EasyExcel.writerSheet(0, "佣金列表")
                    .registerWriteHandler(new CustomWriteHandler())
                    .head(CommissionOrderSheet.class).build();
            excelWriter.write(orderSheets, orderSheet);
        } catch (Exception ioException) {
            ioException.printStackTrace();
        }
    }

    public void exportGroupOrderExcel(AdminOrderPageDto adminOrderPageDto, HttpServletResponse response) {
        // 根据条件获取订单数据
        List<AdminOrderPageVo> list = orderApi.listAdminOrder(adminOrderPageDto).unpack();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // 组装订单明细sheet
        List<GroupOrderSheet> groupOrderSheets = new ArrayList<>();
        // 组装订单汇总sheet
        List<TotalGroupOrderSheet> totalGroupOrderSheets = new ArrayList<>();
        setGroupOrderData(list, groupOrderSheets, totalGroupOrderSheets);

        LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();
        String fileName = "团购订单明细" + LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(6);

        // 多个sheet的输出需要使用ExcelWriter类，这里想要下载成功，需要输出到OutputStream中
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).inMemory(true).build()) {
            // 设置响应类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            // 设置编码格式
            response.setCharacterEncoding("utf-8");
            // 设置跨域
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD, PUT");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "*");
            // 设置响应头
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");

            List<List<String>> mergeColDataList = Stream.of(groupOrderSheets.stream().map(GroupOrderSheet::getOrderNo).collect(Collectors.toList())
            ).collect(Collectors.toList());
            List<Integer> mergeColIndexList = Stream.of(0).collect(Collectors.toList());

            WriteSheet groupOrderSheet = EasyExcel.writerSheet(0, "订单明细")
                    .registerWriteHandler(new CustomWriteHandler())
                    .registerWriteHandler(new CustomCellMergeStrategy(mergeColDataList, mergeColIndexList))
                    .head(GroupOrderSheet.class).build();
            excelWriter.write(groupOrderSheets, groupOrderSheet);
            WriteSheet groupOrderSummarySheet = EasyExcel.writerSheet(1, "订单汇总")
                    .registerWriteHandler(new CustomWriteHandler()).head(TotalGroupOrderSheet.class).build();
            excelWriter.write(totalGroupOrderSheets, groupOrderSummarySheet);
        } catch (Exception ioException) {
            ioException.printStackTrace();
        }
    }

    private void setVerifyRecordData(List<AdminVerifyRecordPageVo> list, List<VerifyRecordSheet> verifyRecordSheets) {
        for (AdminVerifyRecordPageVo adminVerifyRecordPageVo : list) {
            VerifyRecordSheet verifyRecordSheet = new VerifyRecordSheet();
            BeanUtils.copyProperties(adminVerifyRecordPageVo, verifyRecordSheet);
            verifyRecordSheets.add(verifyRecordSheet);
        }
    }

    private void setCommissionOrderData(List<AdminCommissionOrderPageVo> list, List<CommissionOrderSheet> orderSheets) {
        for (AdminCommissionOrderPageVo vo : list) {
            CommissionOrderSheet sheet = new CommissionOrderSheet();
            BeanUtils.copyProperties(vo, sheet);
            orderSheets.add(sheet);
        }
    }

    private void setOrderData(List<AdminOrderPageVo> list, List<GroupOrderSheet> groupOrderSheets) {
        // 核销金额总计=核销的子订单实付金额（分销金额）
        BigDecimal verifyOrderAmt = BigDecimal.ZERO;
        // 订单补贴合计=分账补贴累计
        BigDecimal totalOrderSubsidyAmt = BigDecimal.ZERO;
        // 佣金合计
        BigDecimal totalCommissionAmt = BigDecimal.ZERO;
        // 总补贴金额=分账补贴+佣金
        BigDecimal sumSubsidyAmt = BigDecimal.ZERO;

        for (AdminOrderPageVo adminOrderPageVo : list) {
            // 推广权益
            String promotionEquity = "";
            // 推广权益类型:0-无,1-其他权益,2-佣金 如果是其他权益,则取otherEquity字段数据,如果是佣金,则取actualCommissionAmt实际全核销佣金金额和totalCommissionAmt总实际佣金
            Integer promotionEquityType = adminOrderPageVo.getPromotionEquityType();
            if (promotionEquityType != null) {
                if (promotionEquityType == 1) {
                    promotionEquity = adminOrderPageVo.getOtherEquity();
                } else if (promotionEquityType == 2) {
                    promotionEquity = adminOrderPageVo.getActualCommissionAmt().setScale(2, BigDecimal.ROUND_DOWN).toString();
                }
            }

            // 商品本金合计=是所有商品原本的售价合计
            BigDecimal totalMerchantAmt = BigDecimal.ZERO;
            // 商品补贴合计=分账补贴累加
            BigDecimal subsidyAmt = BigDecimal.ZERO;
            // 订单总补贴=分账补贴累加+佣金
            BigDecimal totalOrderSubsidy = BigDecimal.ZERO;

            List<AdminOrderItemVo> adminOrderItems = adminOrderPageVo.getAdminOrderItems();
            for (AdminOrderItemVo adminOrderItem : adminOrderItems) {
                BigDecimal goodsPrice = adminOrderItem.getGoodsPrice();
                if (goodsPrice != null && goodsPrice.compareTo(BigDecimal.ZERO) > 0) {
                    totalMerchantAmt = totalMerchantAmt.add(goodsPrice);
                }

                BigDecimal totalSubsidyAmt = adminOrderItem.getTotalSubsidyAmt();
                if (totalSubsidyAmt != null && totalSubsidyAmt.compareTo(BigDecimal.ZERO) > 0) {
                    subsidyAmt = subsidyAmt.add(totalSubsidyAmt);
                    totalOrderSubsidy = totalOrderSubsidy.add(totalSubsidyAmt);
                }

                BigDecimal commissionAmt = adminOrderItem.getCommissionAmt();
                if (commissionAmt != null && commissionAmt.compareTo(BigDecimal.ZERO) > 0) {
//                    totalOrderSubsidy = totalOrderSubsidy.add(commissionAmt);
                    subsidyAmt = subsidyAmt.subtract(commissionAmt);
                }

                Integer subOrderState = adminOrderItem.getSubOrderState();
                if (SubOrderStateEnum.VERIFIED.getValue().equals(subOrderState)) {
                    verifyOrderAmt = verifyOrderAmt.add(adminOrderItem.getDistributionOrderAmt());
                }
            }

            totalOrderSubsidyAmt = totalOrderSubsidyAmt.add(subsidyAmt);
            totalCommissionAmt = totalCommissionAmt.add(adminOrderPageVo.getActualCommissionAmt());
            sumSubsidyAmt = sumSubsidyAmt.add(totalOrderSubsidy);


            for (AdminOrderItemVo adminOrderItem : adminOrderItems) {
                GroupOrderSheet groupOrderSheet = new GroupOrderSheet();
                groupOrderSheet.setOrderNo(adminOrderPageVo.getOrderNo());
                groupOrderSheet.setActiveTitle(adminOrderPageVo.getActiveTitle());
                groupOrderSheet.setOrderNum(adminOrderPageVo.getOrderNum());

                groupOrderSheet.setSubOrderNo(adminOrderItem.getSubOrderNo());
                groupOrderSheet.setGoodsName(adminOrderItem.getGoodsName());
                groupOrderSheet.setGoodsPrice(adminOrderItem.getGoodsPrice());
                groupOrderSheet.setMerchantAmt(adminOrderItem.getMerchantAmt());
                groupOrderSheet.setTotalSubsidyAmt(adminOrderItem.getTotalSubsidyAmt());
                groupOrderSheet.setSubOrderState(adminOrderItem.getSubOrderState());
                groupOrderSheet.setMerchantName(adminOrderItem.getMerchantShortName());
                groupOrderSheet.setVerifyTime(adminOrderItem.getVerifyTime());

                groupOrderSheet.setOrderNickName(adminOrderPageVo.getOrderNickName());
                groupOrderSheet.setOrderMobile(adminOrderPageVo.getOrderMobile());
                groupOrderSheet.setOrderPrice(adminOrderPageVo.getOrderPrice());
                groupOrderSheet.setDiscountAmt(adminOrderPageVo.getDiscountAmt());
                groupOrderSheet.setRedPacketAmt(adminOrderPageVo.getRedPacketAmt());
                groupOrderSheet.setPayPrice(adminOrderPageVo.getPayPrice());
                groupOrderSheet.setAgentNickName(adminOrderPageVo.getAgentNickName());
                groupOrderSheet.setAgentMobile(adminOrderPageVo.getAgentMobile());
                groupOrderSheet.setOrderState(adminOrderPageVo.getOrderState());

                groupOrderSheet.setOrderTime(adminOrderPageVo.getOrderTime());
                groupOrderSheet.setPayTime(adminOrderPageVo.getPayTime());
                groupOrderSheet.setFinishTime(adminOrderPageVo.getFinishTime());

                // 推广权益
                groupOrderSheet.setPromotionEquity(promotionEquity);

                // 商品本金合计=是所有商品原本的售价合计
                groupOrderSheet.setTotalMerchantAmt(totalMerchantAmt);
                // 商品补贴合计=分账补贴累加
                groupOrderSheet.setSubsidyAmt(subsidyAmt);
                // 订单总补贴=分账补贴累加+佣金
                groupOrderSheet.setTotalOrderSubsidy(totalOrderSubsidy);

                groupOrderSheets.add(groupOrderSheet);
            }
        }
    }

    private void setPointsOrderData(List<AdminPointsOrderPageVo> list, List<PointsOrderSheet> pointsOrderSheets, List<TotalPointsOrderSheet> totalPointsOrderSheets) {
        // 总订单数
        Integer orderNum = list.size();
        // 核销订单数
        int verifyOrderNum = 0;
        // 核销金额总计=核销的子订单实付金额（分销金额）
        BigDecimal verifyOrderAmt = BigDecimal.ZERO;
        // 商品总金额
        BigDecimal totalGoodsPrice = BigDecimal.ZERO;
        // 下单人数
        Integer orderUserNum = list.stream().map(AdminPointsOrderPageVo::getUserId).collect(Collectors.toSet()).size();

        for (AdminPointsOrderPageVo adminOrderPageVo : list) {
            // 是否是核销订单
            boolean isVerify = false;

            List<AdminOrderItemVo> adminOrderItems = adminOrderPageVo.getAdminOrderItems();
            log.error("adminOrderItems: {}, orderId: {}", adminOrderItems, adminOrderPageVo.getId());
            for (AdminOrderItemVo adminOrderItem : adminOrderItems) {
                BigDecimal goodsPrice = adminOrderItem.getGoodsPrice();
                if (goodsPrice != null && goodsPrice.compareTo(BigDecimal.ZERO) > 0) {
                    totalGoodsPrice = totalGoodsPrice.add(goodsPrice);
                }

                Integer subOrderState = adminOrderItem.getSubOrderState();
                if (SubOrderStateEnum.VERIFIED.getValue().equals(subOrderState)) {
                    isVerify = true;
                    verifyOrderAmt = verifyOrderAmt.add(goodsPrice);
                }
            }

            if (isVerify) {
                verifyOrderNum += 1;
            }

            for (AdminOrderItemVo adminOrderItem : adminOrderItems) {
                PointsOrderSheet orderSheet = new PointsOrderSheet();
                orderSheet.setOrderNo(adminOrderPageVo.getOrderNo());
                orderSheet.setActiveTitle(adminOrderPageVo.getActiveTitle());
                orderSheet.setOrderNum(adminOrderPageVo.getOrderNum());

                orderSheet.setSubOrderNo(adminOrderItem.getSubOrderNo());
                orderSheet.setGoodsPrice(adminOrderItem.getGoodsPrice());
                orderSheet.setSubOrderState(adminOrderItem.getSubOrderState());
                orderSheet.setMerchantName(adminOrderItem.getMerchantShortName());
                orderSheet.setVerifyTime(adminOrderItem.getVerifyTime());

                orderSheet.setOrderNickName(adminOrderPageVo.getOrderNickName());
                orderSheet.setOrderMobile(adminOrderPageVo.getOrderMobile());
                orderSheet.setOrderPrice(adminOrderPageVo.getOrderPrice());
                orderSheet.setPayPrice(adminOrderPageVo.getPayPrice());
                orderSheet.setOrderState(adminOrderPageVo.getOrderState());

                orderSheet.setOrderTime(adminOrderPageVo.getOrderTime());
                orderSheet.setPayTime(adminOrderPageVo.getPayTime());
                orderSheet.setFinishTime(adminOrderPageVo.getFinishTime());

                pointsOrderSheets.add(orderSheet);
            }
        }

        TotalPointsOrderSheet totalPointsOrderSheet = new TotalPointsOrderSheet();
        totalPointsOrderSheet.setOrderNum(orderNum);
        totalPointsOrderSheet.setVerifyOrderNum(verifyOrderNum);
        totalPointsOrderSheet.setVerifyOrderAmt(verifyOrderAmt);
        totalPointsOrderSheet.setTotalOrderPrice(totalGoodsPrice);
        totalPointsOrderSheet.setOrderUserNum(orderUserNum);
        totalPointsOrderSheets.add(totalPointsOrderSheet);
    }

    private void setGroupOrderData(List<AdminOrderPageVo> list, List<GroupOrderSheet> groupOrderSheets, List<TotalGroupOrderSheet> totalGroupOrderSheets) {
        // 总订单数
        Integer orderNum = list.size();
        // 核销订单数
        int verifyOrderNum = 0;
        // 核销金额总计=核销的子订单实付金额（分销金额）
        BigDecimal verifyOrderAmt = BigDecimal.ZERO;
        // 订单补贴合计=分账补贴累计
        BigDecimal totalOrderSubsidyAmt = BigDecimal.ZERO;
        // 佣金合计
        BigDecimal totalCommissionAmt = BigDecimal.ZERO;
        // 总补贴金额=分账补贴+佣金
        BigDecimal sumSubsidyAmt = BigDecimal.ZERO;
        // 下单人数
        Integer orderUserNum = list.stream().map(AdminOrderPageVo::getUserId).collect(Collectors.toSet()).size();

        for (AdminOrderPageVo adminOrderPageVo : list) {
            // 推广权益
            String promotionEquity = "";
            // 推广权益类型:0-无,1-其他权益,2-佣金 如果是其他权益,则取otherEquity字段数据,如果是佣金,则取actualCommissionAmt实际全核销佣金金额和totalCommissionAmt总实际佣金
            Integer promotionEquityType = adminOrderPageVo.getPromotionEquityType();
            if (promotionEquityType == 1) {
                promotionEquity = adminOrderPageVo.getOtherEquity();
            } else if (promotionEquityType == 2) {
                promotionEquity = adminOrderPageVo.getActualCommissionAmt().setScale(2, BigDecimal.ROUND_DOWN).toString();
            }

            // 商品本金合计=是所有商品原本的售价合计
            BigDecimal totalMerchantAmt = BigDecimal.ZERO;
            // 商品补贴合计=分账补贴累加
            BigDecimal subsidyAmt = BigDecimal.ZERO;
            // 订单总补贴=分账补贴累加+佣金
            BigDecimal totalOrderSubsidy = BigDecimal.ZERO;
            // 是否是核销订单
            boolean isVerify = false;

            List<AdminOrderItemVo> adminOrderItems = adminOrderPageVo.getAdminOrderItems();
            if (!CollectionUtils.isEmpty(adminOrderItems)) {
                for (AdminOrderItemVo adminOrderItem : adminOrderItems) {
                    BigDecimal goodsPrice = adminOrderItem.getGoodsPrice();
                    if (goodsPrice != null && goodsPrice.compareTo(BigDecimal.ZERO) > 0) {
                        totalMerchantAmt = totalMerchantAmt.add(goodsPrice);
                    }

                    BigDecimal totalSubsidyAmt = adminOrderItem.getTotalSubsidyAmt();
                    if (totalSubsidyAmt != null && totalSubsidyAmt.compareTo(BigDecimal.ZERO) > 0) {
                        subsidyAmt = subsidyAmt.add(totalSubsidyAmt);
                        totalOrderSubsidy = totalOrderSubsidy.add(totalSubsidyAmt);
                    }

                    BigDecimal commissionAmt = adminOrderItem.getCommissionAmt();
                    if (commissionAmt != null && commissionAmt.compareTo(BigDecimal.ZERO) > 0) {
//                    totalOrderSubsidy = totalOrderSubsidy.add(commissionAmt);
                        subsidyAmt = subsidyAmt.subtract(commissionAmt);
                    }

                    Integer subOrderState = adminOrderItem.getSubOrderState();
                    if (SubOrderStateEnum.VERIFIED.getValue().equals(subOrderState)) {
                        isVerify = true;
                        verifyOrderAmt = verifyOrderAmt.add(adminOrderItem.getDistributionOrderAmt());
                    }
                }

                if (isVerify) {
                    verifyOrderNum += 1;
                }
                totalOrderSubsidyAmt = totalOrderSubsidyAmt.add(subsidyAmt);
                totalCommissionAmt = totalCommissionAmt.add(adminOrderPageVo.getActualCommissionAmt());
                sumSubsidyAmt = sumSubsidyAmt.add(totalOrderSubsidy);

                for (AdminOrderItemVo adminOrderItem : adminOrderItems) {
                    GroupOrderSheet groupOrderSheet = new GroupOrderSheet();
                    groupOrderSheet.setOrderNo(adminOrderPageVo.getOrderNo());
                    groupOrderSheet.setActiveTitle(adminOrderPageVo.getActiveTitle());
                    groupOrderSheet.setOrderNum(adminOrderPageVo.getOrderNum());

                    groupOrderSheet.setSubOrderNo(adminOrderItem.getSubOrderNo());
                    groupOrderSheet.setGoodsName(adminOrderItem.getGoodsName());
                    groupOrderSheet.setGoodsPrice(adminOrderItem.getGoodsPrice());
                    groupOrderSheet.setMerchantAmt(adminOrderItem.getMerchantAmt());
                    groupOrderSheet.setTotalSubsidyAmt(adminOrderItem.getTotalSubsidyAmt());
                    groupOrderSheet.setSubOrderState(adminOrderItem.getSubOrderState());
                    groupOrderSheet.setMerchantName(adminOrderItem.getMerchantShortName());
                    groupOrderSheet.setVerifyTime(adminOrderItem.getVerifyTime());

                    groupOrderSheet.setOrderNickName(adminOrderPageVo.getOrderNickName());
                    groupOrderSheet.setOrderMobile(adminOrderPageVo.getOrderMobile());
                    groupOrderSheet.setOrderPrice(adminOrderPageVo.getOrderPrice());
                    groupOrderSheet.setDiscountAmt(adminOrderPageVo.getDiscountAmt());
                    groupOrderSheet.setRedPacketAmt(adminOrderPageVo.getRedPacketAmt());
                    groupOrderSheet.setPayPrice(adminOrderPageVo.getPayPrice());
                    groupOrderSheet.setAgentNickName(adminOrderPageVo.getAgentNickName());
                    groupOrderSheet.setAgentMobile(adminOrderPageVo.getAgentMobile());
                    groupOrderSheet.setOrderState(adminOrderPageVo.getOrderState());

                    groupOrderSheet.setOrderTime(adminOrderPageVo.getOrderTime());
                    groupOrderSheet.setPayTime(adminOrderPageVo.getPayTime());
                    groupOrderSheet.setFinishTime(adminOrderPageVo.getFinishTime());

                    // 推广权益
                    groupOrderSheet.setPromotionEquity(promotionEquity);

                    // 商品本金合计=是所有商品原本的售价合计
                    groupOrderSheet.setTotalMerchantAmt(totalMerchantAmt);
                    // 商品补贴合计=分账补贴累加
                    groupOrderSheet.setSubsidyAmt(subsidyAmt);
                    // 订单总补贴=分账补贴累加+佣金
                    groupOrderSheet.setTotalOrderSubsidy(totalOrderSubsidy);

                    groupOrderSheets.add(groupOrderSheet);
                }
            }
        }

        TotalGroupOrderSheet totalGroupOrderSheet = new TotalGroupOrderSheet();
        totalGroupOrderSheet.setOrderNum(orderNum);
        totalGroupOrderSheet.setVerifyOrderNum(verifyOrderNum);
        totalGroupOrderSheet.setVerifyOrderAmt(verifyOrderAmt);
        totalGroupOrderSheet.setTotalOrderSubsidyAmt(totalOrderSubsidyAmt);
        totalGroupOrderSheet.setTotalCommissionAmt(totalCommissionAmt);
        totalGroupOrderSheet.setTotalSubsidyAmt(sumSubsidyAmt);
        totalGroupOrderSheet.setOrderUserNum(orderUserNum);
        totalGroupOrderSheets.add(totalGroupOrderSheet);
    }

    public void exportEnrollOrderExcel(AdminOrderPageDto adminOrderPageDto, HttpServletResponse response) {
        // 根据条件获取订单数据
        List<AdminOrderPageVo> list = orderApi.listAdminOrder(adminOrderPageDto).unpack();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // 组装订单明细sheet
        List<EnrollOrderSheet> enrollOrderSheets = new ArrayList<>();
        // 组装订单汇总sheet
        List<TotalEnrollOrderSheet> totalEnrollOrderSheets = new ArrayList<>();
        setEnrollOrderData(list, enrollOrderSheets, totalEnrollOrderSheets);

        LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();
        String fileName = "报名订单明细" + LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(6);

        // 多个sheet的输出需要使用ExcelWriter类，这里想要下载成功，需要输出到OutputStream中
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).inMemory(true).build()) {
            // 设置响应类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            // 设置编码格式
            response.setCharacterEncoding("utf-8");
            // 设置跨域
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD, PUT");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "*");
            // 设置响应头
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");

            List<List<String>> mergeColDataList = Stream.of(enrollOrderSheets.stream().map(EnrollOrderSheet::getOrderNo).collect(Collectors.toList())
            ).collect(Collectors.toList());
            List<Integer> mergeColIndexList = Stream.of(0).collect(Collectors.toList());

            WriteSheet enrollOrderSheet = EasyExcel.writerSheet(0, "订单明细")
                    .registerWriteHandler(new CustomWriteHandler())
                    .registerWriteHandler(new CustomCellMergeStrategy(mergeColDataList, mergeColIndexList))
                    .head(EnrollOrderSheet.class).build();
            excelWriter.write(enrollOrderSheets, enrollOrderSheet);
            WriteSheet enrollOrderSummarySheet = EasyExcel.writerSheet(1, "订单汇总")
                    .registerWriteHandler(new CustomWriteHandler()).head(TotalEnrollOrderSheet.class).build();
            excelWriter.write(totalEnrollOrderSheets, enrollOrderSummarySheet);
        } catch (Exception ioException) {
            ioException.printStackTrace();
        }
    }

    private void setEnrollOrderData(List<AdminOrderPageVo> list, List<EnrollOrderSheet> enrollOrderSheets, List<TotalEnrollOrderSheet> totalEnrollOrderSheets) {
        // 总订单数
        Integer orderNum = list.size();
        // 核销订单数
        int verifyOrderNum = 0;
        // 核销金额总计=核销的子订单实付金额（分销金额）
        BigDecimal verifyOrderAmt = BigDecimal.ZERO;
        // 订单补贴合计=分账补贴累计
        BigDecimal totalOrderSubsidyAmt = BigDecimal.ZERO;
        // 佣金合计
        BigDecimal totalCommissionAmt = BigDecimal.ZERO;
        // 总补贴金额=分账补贴+佣金
        BigDecimal sumSubsidyAmt = BigDecimal.ZERO;
        // 总返现金额
        BigDecimal sumReturnAmt = BigDecimal.ZERO;
        // 下单人数
        Integer orderUserNum = list.stream().map(AdminOrderPageVo::getUserId).collect(Collectors.toSet()).size();

        for (AdminOrderPageVo adminOrderPageVo : list) {
            // 推广权益
            String promotionEquity = "";
            // 推广权益类型:0-无,1-其他权益,2-佣金 如果是其他权益,则取otherEquity字段数据,如果是佣金,则取actualCommissionAmt实际全核销佣金金额和totalCommissionAmt总实际佣金
            Integer promotionEquityType = adminOrderPageVo.getPromotionEquityType();
            if (promotionEquityType == 1) {
                promotionEquity = adminOrderPageVo.getOtherEquity();
            } else if (promotionEquityType == 2) {
                promotionEquity = adminOrderPageVo.getActualCommissionAmt().setScale(2, BigDecimal.ROUND_DOWN).toString();
            }

            // 商品本金合计=是所有商品原本的售价合计
            BigDecimal totalMerchantAmt = BigDecimal.ZERO;
            // 商品补贴合计=分账补贴累加
            BigDecimal subsidyAmt = BigDecimal.ZERO;
            // 订单总补贴=分账补贴累加+佣金
            BigDecimal totalOrderSubsidy = BigDecimal.ZERO;
            // 订单总返现
            BigDecimal totalReturnAmt = BigDecimal.ZERO;
            // 是否是核销订单
            boolean isVerify = false;

            List<AdminOrderItemVo> adminOrderItems = adminOrderPageVo.getAdminOrderItems();
            if (!CollectionUtils.isEmpty(adminOrderItems)) {
                for (AdminOrderItemVo adminOrderItem : adminOrderItems) {
                    BigDecimal goodsPrice = adminOrderItem.getGoodsPrice();
                    if (goodsPrice != null && goodsPrice.compareTo(BigDecimal.ZERO) > 0) {
                        totalMerchantAmt = totalMerchantAmt.add(goodsPrice);
                    }

                    BigDecimal totalSubsidyAmt = adminOrderItem.getTotalSubsidyAmt();
                    if (totalSubsidyAmt != null && totalSubsidyAmt.compareTo(BigDecimal.ZERO) > 0) {
                        subsidyAmt = subsidyAmt.add(totalSubsidyAmt);
                        totalOrderSubsidy = totalOrderSubsidy.add(totalSubsidyAmt);
                    }

                    BigDecimal commissionAmt = adminOrderItem.getCommissionAmt();
                    if (commissionAmt != null && commissionAmt.compareTo(BigDecimal.ZERO) > 0) {
//                    totalOrderSubsidy = totalOrderSubsidy.add(commissionAmt);
                        subsidyAmt = subsidyAmt.subtract(commissionAmt);
                    }

                    Integer subOrderState = adminOrderItem.getSubOrderState();
                    if (SubOrderStateEnum.VERIFIED.getValue().equals(subOrderState)) {
                        isVerify = true;
                        verifyOrderAmt = verifyOrderAmt.add(adminOrderItem.getDistributionOrderAmt());
                        totalReturnAmt = totalReturnAmt.add(adminOrderItem.getReturnAmt());
                    }
                }

                if (isVerify) {
                    verifyOrderNum += 1;
                }
                totalOrderSubsidyAmt = totalOrderSubsidyAmt.add(subsidyAmt);
                totalCommissionAmt = totalCommissionAmt.add(adminOrderPageVo.getActualCommissionAmt());
                sumSubsidyAmt = sumSubsidyAmt.add(totalOrderSubsidy);
                sumReturnAmt = sumReturnAmt.add(totalReturnAmt);


                for (AdminOrderItemVo adminOrderItem : adminOrderItems) {
                    EnrollOrderSheet enrollOrderSheet = new EnrollOrderSheet();
                    enrollOrderSheet.setOrderNo(adminOrderPageVo.getOrderNo());
                    enrollOrderSheet.setActiveTitle(adminOrderPageVo.getActiveTitle());
                    enrollOrderSheet.setOrderNum(adminOrderPageVo.getOrderNum());

                    enrollOrderSheet.setSubOrderNo(adminOrderItem.getSubOrderNo());
                    enrollOrderSheet.setGoodsPrice(adminOrderItem.getGoodsPrice());
                    enrollOrderSheet.setMerchantAmt(adminOrderItem.getMerchantAmt());
                    enrollOrderSheet.setTotalSubsidyAmt(adminOrderItem.getTotalSubsidyAmt());
                    enrollOrderSheet.setSubOrderState(adminOrderItem.getSubOrderState());
                    enrollOrderSheet.setMerchantName(adminOrderItem.getMerchantShortName());
                    enrollOrderSheet.setVerifyTime(adminOrderItem.getVerifyTime());

                    enrollOrderSheet.setOrderNickName(adminOrderPageVo.getOrderNickName());
                    enrollOrderSheet.setOrderMobile(adminOrderPageVo.getOrderMobile());
                    enrollOrderSheet.setOrderPrice(adminOrderPageVo.getOrderPrice());
                    enrollOrderSheet.setDiscountAmt(adminOrderPageVo.getDiscountAmt());
                    enrollOrderSheet.setRedPacketAmt(adminOrderPageVo.getRedPacketAmt());
                    enrollOrderSheet.setPayPrice(adminOrderPageVo.getPayPrice());
                    enrollOrderSheet.setAgentNickName(adminOrderPageVo.getAgentNickName());
                    enrollOrderSheet.setAgentMobile(adminOrderPageVo.getAgentMobile());
                    enrollOrderSheet.setOrderState(adminOrderPageVo.getOrderState());

                    enrollOrderSheet.setOrderTime(adminOrderPageVo.getOrderTime());
                    enrollOrderSheet.setPayTime(adminOrderPageVo.getPayTime());
                    enrollOrderSheet.setFinishTime(adminOrderPageVo.getFinishTime());

                    // 推广权益
                    enrollOrderSheet.setPromotionEquity(promotionEquity);

                    // 商品本金合计=是所有商品原本的售价合计
//                groupOrderSheet.setTotalMerchantAmt(totalMerchantAmt);
                    // 商品补贴合计=分账补贴累加
//                groupOrderSheet.setSubsidyAmt(subsidyAmt);
                    // 订单总补贴=分账补贴累加+佣金
                    enrollOrderSheet.setTotalOrderSubsidy(totalOrderSubsidy);
                    // 订单总返现
                    enrollOrderSheet.setTotalReturnAmt(totalReturnAmt);

                    // 处理报名信息
                    enrollInfoHandle(adminOrderItem, enrollOrderSheet);

                    enrollOrderSheets.add(enrollOrderSheet);
                }
            }
        }

        TotalEnrollOrderSheet totalEnrollOrderSheet = new TotalEnrollOrderSheet();
        totalEnrollOrderSheet.setOrderNum(orderNum);
        totalEnrollOrderSheet.setVerifyOrderNum(verifyOrderNum);
        totalEnrollOrderSheet.setVerifyOrderAmt(verifyOrderAmt);
        totalEnrollOrderSheet.setTotalOrderSubsidyAmt(totalOrderSubsidyAmt);
        totalEnrollOrderSheet.setTotalCommissionAmt(totalCommissionAmt);
        totalEnrollOrderSheet.setTotalSubsidyAmt(sumSubsidyAmt);
        totalEnrollOrderSheet.setTotalReturnAmt(sumReturnAmt);
        totalEnrollOrderSheet.setOrderUserNum(orderUserNum);
        totalEnrollOrderSheets.add(totalEnrollOrderSheet);
    }

    private void enrollInfoHandle(AdminOrderItemVo adminOrderItem, EnrollOrderSheet enrollOrderSheet) {
        String enrollInfo = adminOrderItem.getEnrollInfo();
        if (!StringUtils.isBlank(enrollInfo)) {
            List<ActiveEnrollInfoSonDto> activeEnrollInfoSonDtos = JSON.parseArray(enrollInfo, ActiveEnrollInfoSonDto.class);
            // 根据排序值正序
            List<ActiveEnrollInfoSonDto> sortActiveEnrollInfoSonDtos = activeEnrollInfoSonDtos.stream()
                    .sorted(Comparator.comparing(ActiveEnrollInfoSonDto::getSort))
                    .collect(Collectors.toList());
            for (int i = 0; i < sortActiveEnrollInfoSonDtos.size(); i++) {
                ActiveEnrollInfoSonDto sortActiveEnrollInfoSonDto = sortActiveEnrollInfoSonDtos.get(i);
                String title = sortActiveEnrollInfoSonDto.getTitle();
                String result = "";

                // 类型(1-填写项，2-单选项，3-多选项)
                Integer type = sortActiveEnrollInfoSonDto.getType();
                if (ActiveEnrollInfoTypeEnum.WRITE.getValue().equals(type)) {
                    // 填写项
                    result = sortActiveEnrollInfoSonDto.getContent();
                } else if (ActiveEnrollInfoTypeEnum.SINGLE.getValue().equals(type)) {
                    // 单选项
                    List<ActiveEnrollInfoOptionDto> activeEnrollInfoOptions = sortActiveEnrollInfoSonDto.getActiveEnrollInfoOptions();
                    if (!CollectionUtils.isEmpty(activeEnrollInfoOptions)) {
                        for (ActiveEnrollInfoOptionDto activeEnrollInfoOption : activeEnrollInfoOptions) {
                            // 勾选状态：1-未勾选，2-已勾选
                            Integer checkState = activeEnrollInfoOption.getCheckState();
                            if (checkState != null && checkState == 2) {
                                result = activeEnrollInfoOption.getOptionText();
                                break;
                            }
                        }
                    }
                } else if (ActiveEnrollInfoTypeEnum.MULTIPLE.getValue().equals(type)) {
                    // 多选项
                    StringBuilder valueStringBuilder = new StringBuilder();
                    List<ActiveEnrollInfoOptionDto> activeEnrollInfoOptions = sortActiveEnrollInfoSonDto.getActiveEnrollInfoOptions();
                    if (!CollectionUtils.isEmpty(activeEnrollInfoOptions)) {
                        for (ActiveEnrollInfoOptionDto activeEnrollInfoOption : activeEnrollInfoOptions) {
                            // 勾选状态：1-未勾选，2-已勾选
                            Integer checkState = activeEnrollInfoOption.getCheckState();
                            if (checkState != null && checkState == 2) {
                                valueStringBuilder.append(activeEnrollInfoOption.getOptionText()).append("、");
                            }
                        }

                        if (valueStringBuilder.length() > 0) {
                            result = valueStringBuilder.deleteCharAt(valueStringBuilder.length() - 1).toString();
                        }
                    }
                }

                if (i == 0) {
                    enrollOrderSheet.setEnrollTitleOne(title);
                    enrollOrderSheet.setEnrollInfoOne(result);
                } else if (i == 1) {
                    enrollOrderSheet.setEnrollTitleTwo(title);
                    enrollOrderSheet.setEnrollInfoTwo(result);
                } else if (i == 2) {
                    enrollOrderSheet.setEnrollTitleThree(title);
                    enrollOrderSheet.setEnrollInfoThree(result);
                } else if (i == 3) {
                    enrollOrderSheet.setEnrollTitleFour(title);
                    enrollOrderSheet.setEnrollInfoFour(result);
                } else if (i == 4) {
                    enrollOrderSheet.setEnrollTitleFive(title);
                    enrollOrderSheet.setEnrollInfoFive(result);
                } else if (i == 5) {
                    enrollOrderSheet.setEnrollTitleSix(title);
                    enrollOrderSheet.setEnrollInfoSix(result);
                } else if (i == 6) {
                    enrollOrderSheet.setEnrollTitleSeven(title);
                    enrollOrderSheet.setEnrollInfoSeven(result);
                } else if (i == 7) {
                    enrollOrderSheet.setEnrollTitleEight(title);
                    enrollOrderSheet.setEnrollInfoEight(result);
                } else if (i == 8) {
                    enrollOrderSheet.setEnrollTitleNine(title);
                    enrollOrderSheet.setEnrollInfoNine(result);
                } else if (i == 9) {
                    enrollOrderSheet.setEnrollTitleTen(title);
                    enrollOrderSheet.setEnrollInfoTen(result);
                }
            }
        }
    }
}
